package com.yc.cloud.openai.portal.service.impl;

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yc.cloud.common.basic.dto.BaseQueryParam;
import com.yc.cloud.common.basic.exception.Asserts;
import com.yc.cloud.openai.entity.GptDataset;
import com.yc.cloud.openai.mapper.GptDatasetMapper;
import com.yc.cloud.openai.portal.common.PortalErrorTips;
import com.yc.cloud.openai.portal.dao.GPTChatClient;
import com.yc.cloud.openai.portal.dto.gpt.GptDatasetCreateDto;
import com.yc.cloud.openai.portal.dto.gpt.GptDatasetUpdateParam;
import com.yc.cloud.openai.portal.dto.request.GptDatasetCreateParam;
import com.yc.cloud.openai.portal.dto.request.GptDatasetDeleteParam;
import com.yc.cloud.openai.portal.dto.response.GPTChatResponseResult;
import com.yc.cloud.openai.portal.enums.GPTChatProvider;
import com.yc.cloud.openai.portal.service.GptDatasetService;
import com.yc.cloud.openai.portal.vo.gpt.GptDatasetVo;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.val;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * AI绘画记录 服务实现类
 * </p>
 *
 * @author Yancy
 * @since 2025-01-07
 */
@Service
@Slf4j
public class GptDatasetServiceImpl extends ServiceImpl<GptDatasetMapper, GptDataset> implements GptDatasetService {

    private final Map<GPTChatProvider, GPTChatClient> chatClients = new EnumMap<>(GPTChatProvider.class);

    public GptDatasetServiceImpl(Map<String, GPTChatClient> chatClientMap) {
        // 使用枚举的 value 作为键来初始化 Map
        chatClientMap.forEach((name, client) -> chatClients.put(GPTChatProvider.valueOf(name), client));
    }

    @Override
    public IPage<GptDatasetVo> list(BaseQueryParam queryParam) {
        val query = new QueryWrapper<GptDataset>();
        IPage<GptDataset> page;
        // 排序
        if (StrUtil.isNotEmpty(queryParam.getSortBy())) {
            if (BaseQueryParam.ORDER_DESC.equals(queryParam.getOrder())) {
                query.orderByDesc(queryParam.getSortBy());
            } else if (BaseQueryParam.ORDER_ASC.equals(queryParam.getOrder())) {
                query.orderByAsc(queryParam.getSortBy());
            }
        }
        // 模糊查询
        if (StrUtil.isNotEmpty(queryParam.getKeyword())) {
            query.and(queryWrapper -> {
                    queryWrapper.like(GptDataset.NAME, queryParam.getKeyword()).or().like(GptDataset.DESCRIPTION, queryParam.getKeyword());
            });
        }
        // 分页
        if (queryParam.getPage()) {
            page = new Page<>(queryParam.getPageNum(), queryParam.getPageSize(), true);
        } else {
            page = new Page<>(queryParam.getPageNum(), baseMapper.selectCount(query), true);
        }
        val result = baseMapper.selectPage(page, query);
        return result.convert(this::convertVo);
    }

    @Override
    public GptDatasetVo create(GptDatasetCreateParam param) {
        val client = chatClients.get(GPTChatProvider.fromKey(param.getProvider()));
        if (client == null) {
            throw new IllegalArgumentException("Invalid provider: " + param.getProvider());
        }
        // 构建创建参数
        val gptDatasetCreateDto = new GptDatasetCreateDto();
        gptDatasetCreateDto.setName(param.getName());
        gptDatasetCreateDto.setDescription(param.getDescription());
        // 设置向量模型和代理模型
        gptDatasetCreateDto.setVectorModel("dmeta-embedding-zh");
        gptDatasetCreateDto.setAgentModel("gemma:7b");
        // 创建知识库
        val response = client.createDataset(gptDatasetCreateDto);
        if (response.getCode() != GPTChatResponseResult.SUCCESS_CODE) {
            Asserts.fail(response.getMessage());
        }
        val gptdataset = new GptDataset();
        BeanUtils.copyProperties(param, gptdataset);
        // 设置知识库ID
        gptdataset.setDatasetId(response.getData().toString());
        // 设置向量模型和代理模型存入数据库
        gptdataset.setAgentModel(gptDatasetCreateDto.getAgentModel());
        gptdataset.setVectorModel(gptDatasetCreateDto.getVectorModel());
        val saveFlag = save(gptdataset);
        return saveFlag ? convertVo(gptdataset) : null;
    }

    @Override
    public GptDatasetVo get(Long id) {
        return convertVo(getById(id));
    }

    @Override
    public boolean delete(Long id, GptDatasetDeleteParam param) {
        val client = chatClients.get(GPTChatProvider.fromKey(param.getProvider()));
        if (client == null) {
            throw new IllegalArgumentException("Invalid provider: " + param.getProvider());
        }
        val gptDataset = getById(id);
        if (gptDataset == null) {
            Asserts.fail(PortalErrorTips.DATASET_NOT_FOUND);
        }
        if (StrUtil.isNotEmpty(gptDataset.getDatasetId())) {
            val deleteDatasetResult = client.deleteDataset(gptDataset.getDatasetId());
            if (deleteDatasetResult.getCode() != GPTChatResponseResult.SUCCESS_CODE) {
                log.error("删除知识库失败,错误信息:{}", deleteDatasetResult.getMessage());
                //这个错误情况下脏数据,不抛异常,让他继续执行删除业务
                if (!"core.dataset.error.unExistDataset".equals(deleteDatasetResult.getMessage())) {
                    Asserts.fail(deleteDatasetResult.getMessage());
                }
            }
        }
        return removeById(id);
    }

    @Override
    public GptDatasetVo update(Long id, GptDatasetUpdateParam param) {
        val gptdataset = getById(id);
        if (gptdataset == null) {
            Asserts.fail(PortalErrorTips.DATASET_NOT_FOUND);
        }
        // 目前第三方并不支持修改
        // val client = chatClients.get(GPTChatProvider.fromKey(param.getProvider()));
        // if (client == null) {
        // throw new IllegalArgumentException("Invalid provider: " +
        // param.getProvider());
        // }
        // // 构建更新参数
        // val gptDatasetUpdateDto = new GptDatasetUpdateDto();
        // gptDatasetUpdateDto.setName(param.getName());
        // gptDatasetUpdateDto.setDescription(param.getDescription());
        // // 更新知识库
        // val response = client.updateDataset(gptDatasetUpdateDto);
        // if (response.getCode() != GPTChatResponseResult.SUCCESS_CODE) {
        // Asserts.fail(response.getMessage());
        // }
        BeanUtils.copyProperties(param, gptdataset);
        gptdataset.setId(id);
        val updateFlag = updateById(gptdataset);
        return updateFlag ? convertVo(gptdataset) : null;
    }

    @Override
    public GptDatasetVo convertVo(GptDataset gptdataset) {
        if (gptdataset == null) {
            return null;
        }
        val vo = new GptDatasetVo();
        BeanUtils.copyProperties(gptdataset, vo);
        return vo;
    }

    @Override
    public List<GptDatasetVo> convertVo(List<GptDataset> GptDatasetList) {
        if (CollUtil.isNotEmpty(GptDatasetList)) {
            return GptDatasetList.stream().map(this::convertVo).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

}
